import { getPublicKey, putPublicKey } from '@/api/aes'
import CryptoJS from 'crypto-js'
import qs from 'qs'
import JSEncrypt from 'jsencrypt'
import { use_encryption_store } from '@/store/encryption'
import { loadingFullSreen } from '@/utils/utils'

function generateBase64Key(length) {
  // 生成随机字节
  const randomBytes = CryptoJS.lib.WordArray.random(length)
  return CryptoJS.enc.Base64.stringify(randomBytes)
}

function getSecretKey() {
  // 生成256位的Base64编码的AES密钥（32字节）
  const base64AESKey256 = generateBase64Key(32)
  return base64AESKey256
}

export function getAES(content) {
  // console.log(content, 'content')
  let encryptionStore = use_encryption_store()
  /*----------------------------------------------AES加密-----------------------------------------------------*/
  const key = CryptoJS.enc.Base64.parse(encryptionStore.secretKey)
  // 使用密钥加密明文
  const encrypted = CryptoJS.AES.encrypt(content, key, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 })
  // 将加密结果转换为 Base64 字符串
  const encryptedBase64 = encrypted.toString()
  // console.log('加密后Base64:', encryptedBase64)
  return encryptedBase64
}

// 加密
export function encryption(config) {
  // console.log(config, 'config')

  // 请求头添加会话标识
  let { interactiveId } = use_encryption_store()
  interactiveId && (config.headers['Interactive-Control'] = interactiveId)

  let { ignoreEncryption } = config
  // 有的接口不需要加密
  if (ignoreEncryption) return

  let pParams = getAES(qs.stringify(config.params))
  let pData = getAES(JSON.stringify(config.data))
  // 正式环境清空参数
  if (import.meta.env.VITE_BASE_ENV === 'production') {
    config.params = {} // 清空请求体
    config.data = {} // 清空请求体
  }
  // 初始化参数
  config.params = config.params || {}
  config.data = config.data || {}
  config.params.p = pParams
  config.data.data = pData
}

// 解密
export function decrypt(response) {
  // 有的接口不需要解密
  if (response.config.ignoreDecrypt) return
  if (response.data.data) {
    try {
      let encryptionStore = use_encryption_store()
      const key = CryptoJS.enc.Base64.parse(encryptionStore.secretKey)
      /*----------------------------------------------使用AES解密-----------------------------------------------------*/
      // 将 Base64 密文解码为 WordArray 对象
      const encryptedWordArray = CryptoJS.enc.Base64.parse(response.data.data)
      // 解密
      const decrypted = CryptoJS.AES.decrypt({ ciphertext: encryptedWordArray }, key, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 })
      // 将解密后的 WordArray 转换为字符串
      const decryptedBase64 = decrypted.toString(CryptoJS.enc.Utf8)
      try {
        response.data.data = JSON.parse(decryptedBase64)
      } catch (err) {
        response.data.data = decryptedBase64
      }
    } catch (err) {
      // console.log(response.data.data, '请求返回体数据')
      // console.log(err, 'err')
    }
  }
}

export async function createSecretAndPublicKey() {
  // 开启全屏loading
  loadingFullSreen.open()
  let res = await getPublicKey()
  let { key, interactiveId } = res.data
  let encryptionStore = use_encryption_store()
  // console.log(res.data, 'res.data')
  // 保存下发的标识会话请求的唯一id
  encryptionStore.interactiveId = interactiveId
  encryptionStore.secretKey = getSecretKey()
  // rsa公钥
  let rsaPublicKey = key
  // 设置公钥
  const publicKey = `
    -----BEGIN PUBLIC KEY-----
    ${rsaPublicKey}
    -----END PUBLIC KEY-----
    `
  // 创建JSEncrypt实例
  const encryptor = new JSEncrypt()
  encryptor.setPublicKey(publicKey)
  // 要加密的数据
  const dataToEncrypt = `{"key":"${encryptionStore.secretKey}"}`
  // 进行加密
  const encryptedData = encryptor.encrypt(dataToEncrypt)
  await putPublicKey({ data: encryptedData })
  // 关闭全屏loading
  loadingFullSreen.close()
  encryptionStore.done = true
}

// 定时刷新秘钥
setInterval(() => {
  createSecretAndPublicKey()
}, 2 * 60 * 60 * 1000)
